package vnu;

import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.core.behaviours.OneShotBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.UnreadableException;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;


import vocabulary.MyMapVoca;

/**
 * @author NguyenLan
 *
 */
/**
 * @author NguyenLan
 *
 */
public class AgentManager extends Agent implements MyMapVoca{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private ArrayList<AgentInfo> current = new ArrayList<AgentInfo>()
			;
	private AID target= null;

	ArrayList<AgentInfo> getCurrent() {
		return current;
	}
	void setCurrent(ArrayList<AgentInfo> current) {
		this.current = current;
	}

	private AgentInfo getAgentByName(String name){
	
		for (int j = 0; j < current.size(); j++) 
			if(current.get(j).getLocal_Name().equalsIgnoreCase(name)==true){
				AgentInfo temp = current.get(j);
			return temp;
			}
		
	return null;	
}
	 void replyNotUnderstood(ACLMessage msg) {
		try {
			String content = msg.getContent();
			ACLMessage reply = msg.createReply();
			reply.setPerformative(ACLMessage.NOT_UNDERSTOOD);
			reply.setContentObject(content);
			send(reply);
			System.out.println("[Agent manager] Not understood receivedMessage");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	private boolean isExist(AgentInfo input){
		for (int i = 0; i < current.size(); i++) {
			if(input.getLocal_Name().equalsIgnoreCase(current.get(i).getLocal_Name()))
				return true;
			
		}
		return false;
	}
	private void editAgeninfo(AgentInfo name){
		for (int i = 0; i < current.size(); i++) {
			if(current.get(i).getLocal_Name().equalsIgnoreCase(name.getLocal_Name()))
				current.get(i).setAddress(name.getAddress());
		}
	}
	class RegisterInDF extends OneShotBehaviour{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		
		
		RegisterInDF(Agent a){
			super(a);
		}
		
		public void action(){
			getContentManager();	
		}	
	}
	@Override
	protected void setup() {
		// TODO Auto-generated method stub
		super.setup();
		getAID().setLocalName(AGENT_MANAGER);
		System.out.println("Hello World. I am an Manager agent!");
		System.out.println("My LocalName: " + getAID().getLocalName());
		System.out.println("My Name: " + getAID().getName());
		System.out.println("My Address: " + getAID().getAddressesArray()[0]);
		addBehaviour(new RecievedMess(this));
	}	
	
	/**
	 * Test searchAddress function
	 */
	private void printOut(){
		System.out.println("ket quả search "+searchAddress("mob"));
	}
	class RecievedMess extends CyclicBehaviour{
		private static final long serialVersionUID = 1L;
		public RecievedMess(Agent a){
			super(a);
		}
		@Override
		public void action() {
			// TODO Auto-generated method stub
			ACLMessage received = receive();
			if(received == null){
				block();
				return;
			}
			//---------------------------------------------------
			if(received != null){
			try {
			//	AgentInfo content = (AgentInfo) received.getContentObject();
				switch (received.getPerformative()) {
				case (ACLMessage.REQUEST): // Job Agent requires sending message
					
					System.out.println("Request from " + received.getSender().getLocalName());
					addBehaviour(new HandleAgentRequirement(myAgent,received));
					break;
					
				case (ACLMessage.INFORM): //Job Agent informs creating or updating state
						AgentInfo contenti = (AgentInfo) received.getContentObject();
						if(!isExist(contenti)) // Creating a new agent case
							current.add(contenti);
							else
								editAgeninfo(contenti); // Updating an existed agent case
								System.out.println("[Agent manager] Da cap nhat....");
								printOut();	
								break;
				default:
				//	replyNotUnderstood(received);
					break;
				}
				
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
}

}
	class HandleAgentRequirement extends OneShotBehaviour{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private ACLMessage request;
		HandleAgentRequirement(Agent a, ACLMessage request){
			super(a);
			this.request=request;
		}
		@Override
		public void action() {
			
			try {
				ACLMessageX content =(ACLMessageX) request.getContentObject();
				content.setSource(request.getSender());
				forwarding(content);
				
			} catch (UnreadableException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}

	
		private void forwarding(ACLMessageX message){
			ACLMessage forword = new ACLMessage();
			String destination = message.getDestination();
			target = new AID(destination, AID.ISLOCALNAME);
			target.addAddresses(searchAddress(destination));
			forword.addReceiver(target);
			try {
				forword.setContentObject(message);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			send(forword);
			System.out.println("[Agent manager] is forwarding message.....");
		
			
		}
	}

	private String searchAddress(String destination) {
		// TODO Auto-generated method stub
		
		for (int i = 0; i < current.size(); i++) {
			String temp = current.get(i).getLocal_Name();
			if(temp.equalsIgnoreCase(destination))
				return current.get(i).getAddress();
			
		}
		return null;
	}
}
